﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Shapes;
using Bookvar.Common;
using Bookvar.ObjectModel;
using Bookvar.UI.Converters;
using Bookvar.UI.ViewModel.LiveImages;

namespace Bookvar.UI.DragDrop
{
    public abstract class DropTargetAdvisorBase : IDropTargetAdvisor
    {
        private UIElement targetUIElement;

        public UIElement TargetElement
        {
            get { return targetUIElement; }
            set { targetUIElement = value; }
        }

        public abstract bool IsValidDataObject( IDataObject obj );

        public abstract void OnDropCompleted( DragEventArgs args, Point dropPoint );

        public UIElement GetVisualFeedback( IDataObject obj )
        {
            UIElement element = null;
            if (obj.GetDataPresent(BookvarDataFormats.Topic.Name))
            {
                element = obj.GetData( BookvarDataFormats.Topic.Name ) as TopicContentPresenter;
            }
            else if ( obj.GetDataPresent( DataFormats.FileDrop) )
            {
                var fileNames = (string[]) obj.GetData( DataFormats.FileDrop );
                if ( fileNames != null && fileNames.Length > 0 )
                {
                    var image = new Image();
                    if ( FileUtility.IsImage( fileNames[0] ) )
                    {
                        image.Source = (ImageSource) new ImageSourceConverter().ConvertFrom( fileNames[ 0 ] );
                    }
                    else
                    {
                        image.Source =
                            (ImageSource) FileNameToImageSourceConverter.Instance.ConvertFrom( fileNames[ 0 ] );
                    }

                    image.Arrange(new Rect(new Size(image.Source.Width, image.Source.Height)));
                    element = image;
                }
            } 
            else if (obj.GetDataPresent(BookvarDataFormats.ImageInfo.Name))
            {
                var info = (ImageInfo) obj.GetData( BookvarDataFormats.ImageInfo.Name );
                if (info != null)
                {
                    var image = new Image();
                    image.Stretch = Stretch.Fill;
                    image.Source = (ImageSource) new ImageSourceConverter().ConvertFrom( info.ImageUri );
                    image.Arrange( new Rect( new Size( info.Width, info.Height ) ) );
                    element = image;
                }
            }
            else if (obj.GetDataPresent(BookvarDataFormats.LiveImageInfo.Name))
            {
                var info = (LiveImageInfo)obj.GetData(BookvarDataFormats.LiveImageInfo.Name);
                if (info != null)
                {
                    var image = new Image();
                    image.Source = info.ThumbnailSource;
                    image.Height = info.ImageSize.Height;
                    image.Width = info.ImageSize.Width;

                    element = image;
                }
            }

            if ( element != null )
            {
                var frameworkElement = element as FrameworkElement;
                if (frameworkElement != null)
                {
                    var rect = new Rectangle();
                    rect.Width = frameworkElement.ActualWidth > 0 ? frameworkElement.ActualWidth : frameworkElement.Width;
                    rect.Height = frameworkElement.ActualHeight > 0 ? frameworkElement.ActualHeight : frameworkElement.Height;
                    rect.Fill = new VisualBrush(frameworkElement);
                    rect.Opacity = 0.5;
                    rect.IsHitTestVisible = false;
                    return rect;
                }
                
            }
            return null;
        }

        public Point GetOffsetPoint( IDataObject obj )
        {
            if ( obj.GetDataPresent( BookvarDataFormats.OffsetPoint.Name) )
            {
                return (Point) obj.GetData( BookvarDataFormats.OffsetPoint.Name );
            }
            return new Point();
        }
    }
}
